package com.yuanchu.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.common.utils.PageUtils;
import com.yuanchu.common.utils.Query;
import com.yuanchu.goods.dao.YoshopCategoryDao;
import com.yuanchu.goods.dto.EditGoodsCategoryDto;
import com.yuanchu.goods.dto.GoodsCategoryParamsDto;
import com.yuanchu.goods.entity.YoshopCategoryEntity;
import com.yuanchu.goods.service.YoshopCategoryService;
import com.yuanchu.goods.service.YoshopUploadFileService;
import com.yuanchu.goods.utils.RedisUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("yoshopCategoryService")
public class YoshopCategoryServiceImpl extends ServiceImpl<YoshopCategoryDao, YoshopCategoryEntity> implements YoshopCategoryService {

    @Resource
    private YoshopUploadFileService yoshopUploadFileService;
    @Resource
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<YoshopCategoryEntity> page = this.page(
                new Query<YoshopCategoryEntity>().getPage(params),
                new QueryWrapper<YoshopCategoryEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public List<YoshopCategoryEntity> queryGoodsCategory(Map<String, Object> params) {

        String cacheKey = "category:list";
        if (redisUtils.hasKey(cacheKey)) {
            return (List<YoshopCategoryEntity>) redisUtils.get(cacheKey);
        }

        LambdaQueryWrapper<YoshopCategoryEntity> lqw = new LambdaQueryWrapper<>();
        // lqw.eq(YoshopCategoryEntity::getStatus, "1");
        // 指定字段查询
        // lqw.select(YoshopCategoryEntity::getCategoryId, YoshopCategoryEntity::getName, YoshopCategoryEntity::getParentId);
        List<YoshopCategoryEntity> list = this.list(lqw);
        // 一级分类
        List<YoshopCategoryEntity> categoryEntities = list.stream()
                .filter(yoshopCategoryEntity -> yoshopCategoryEntity.getParentId() == 0)
                .map(menu -> {
                    // 设置一级分类子分类
                    menu.setChildren(getChildren(menu, list));
                    // 设置一级分类图片
                    menu.setImage(yoshopUploadFileService.getUploadFileById(menu.getImageId()));
                    return menu;
                })
                .sorted(Comparator.comparingInt(YoshopCategoryEntity::getSort))
                .collect(Collectors.toList());
        // 设置缓存
        redisUtils.set(cacheKey, categoryEntities);

        return categoryEntities;
    }

    @Transactional
    @Override
    public void addGoodsCategory(GoodsCategoryParamsDto goodsCategory, Integer storeId) {
        YoshopCategoryEntity categoryEntity = new YoshopCategoryEntity();
        BeanUtils.copyProperties(goodsCategory.getForm(), categoryEntity);
        categoryEntity.setStoreId(storeId);
        categoryEntity.setCreateTime(System.currentTimeMillis() / 1000);
        categoryEntity.setUpdateTime(System.currentTimeMillis() / 1000);
        boolean save = this.save(categoryEntity);
        if (!save) {
            throw new YuanChuException("添加分类失败");
        }
        // 删除缓存
        redisUtils.del("category:list");
    }

    @Override
    public void editGoodsCategory(EditGoodsCategoryDto goodsCategoryParams, int storeId) {
        YoshopCategoryEntity goodsCategory = goodsCategoryParams.getForm();
        YoshopCategoryEntity categoryEntity = new YoshopCategoryEntity();
        BeanUtils.copyProperties(goodsCategory, categoryEntity);
        categoryEntity.setCategoryId(goodsCategoryParams.getCategoryId());
        categoryEntity.setStoreId(storeId);
        categoryEntity.setCreateTime(System.currentTimeMillis() / 1000);
        categoryEntity.setUpdateTime(System.currentTimeMillis() / 1000);
        boolean update = this.updateById(categoryEntity);
        if (!update) {
            throw new YuanChuException("修改分类失败");
        }
        // 删除缓存
        redisUtils.del("category:list");
    }

    @Transactional
    @Override
    public void deleteGoodsCategoryById(Integer categoryId, int storeId) {
        // 查询分类id是否含有子分类
        if (this.count(new LambdaQueryWrapper<YoshopCategoryEntity>()
                .eq(YoshopCategoryEntity::getParentId, categoryId).eq(YoshopCategoryEntity::getStoreId, storeId)) > 0) {
            throw new YuanChuException("该分类下有子分类，不能删除");
        }
        boolean remove = this.remove(new LambdaQueryWrapper<YoshopCategoryEntity>()
                .eq(YoshopCategoryEntity::getCategoryId, categoryId).eq(YoshopCategoryEntity::getStoreId, storeId));
        if (!remove) {
            throw new YuanChuException("删除分类失败");
        }
        // 删除缓存
        redisUtils.del("category:list");
    }

    @Override
    public boolean updateGoodsCategoryState(EditGoodsCategoryDto goodsCategoryParams) {
        if (goodsCategoryParams.getStatus() == null) {
            return false;
        }
        int status = goodsCategoryParams.getStatus();
        if (status == 1) {
            boolean update = this.update(new UpdateWrapper<YoshopCategoryEntity>()
                    .eq("category_id", goodsCategoryParams.getCategoryId())
                    .set("status", 0)
                    .set("update_time", System.currentTimeMillis() / 1000));
            if (!update) {
                throw new YuanChuException("修改分类状态失败");
            }
            // 删除缓存
            redisUtils.del("category:list");
            return true;
        }else if (status == 0) {
            boolean update = this.update(new UpdateWrapper<YoshopCategoryEntity>()
                    .eq("category_id", goodsCategoryParams.getCategoryId())
                    .set("status", 1)
                    .set("update_time", System.currentTimeMillis() / 1000));
            if (!update) {
                throw new YuanChuException("修改分类状态失败");
            }
            // 删除缓存
            redisUtils.del("category:list");
            return true;
        }

        return false;
    }

    // 递归获取子菜单
    private List<YoshopCategoryEntity> getChildren(YoshopCategoryEntity menu, List<YoshopCategoryEntity> list) {

        List<YoshopCategoryEntity> categoryLevel = list.stream()
                .filter(yoshopCategoryEntity -> yoshopCategoryEntity.getParentId().equals(menu.getCategoryId()))
                .map(category -> {
                    // 设置子分类子分类
                    category.setChildren(getChildren(category, list));
                    // 设置子分类图片
                    category.setImage(yoshopUploadFileService.getUploadFileById(category.getImageId()));
                    return category;
                })
                //根据sort字段字段排序(数字越小越靠前)
                .sorted(Comparator.comparingInt(YoshopCategoryEntity::getSort))
                .collect(Collectors.toList());

        return categoryLevel;
    }

}